package com.ecoolex.hotel.saas.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.framework.common.util.RandomUtil;
import com.ecoolex.hotel.saas.core.dao.PresaleCouponOrderDAO;
import com.ecoolex.hotel.saas.entity.Distribution;
import com.ecoolex.hotel.saas.entity.PaymentOrder;
import com.ecoolex.hotel.saas.entity.PresaleCoupon;
import com.ecoolex.hotel.saas.entity.PresaleCouponDistribtion;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder.Column;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSales;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetail;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderExample;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderExample.Criteria;
import com.ecoolex.hotel.saas.entity.SalesUser;
import com.ecoolex.hotel.saas.enums.*;
import com.ecoolex.hotel.saas.pojo.QueryPresaleCouponOrderDTO;
import com.ecoolex.hotel.saas.pojo.SubmitPresaleCouponOrderDTO;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.Date;
import java.util.List;

import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PresaleCouponOrderManager {
	
    @Autowired
    private PresaleCouponOrderDAO dao;
    
    @Autowired
    private PresaleCouponManager presaleCouponManager;
    
    @Autowired
    private PresaleCouponOrderDetailManager detailManager;
    
    @Autowired
    private SalesUserManager salesUserManager;
    
    @Autowired
    private PresaleCouponDistribtionManager presaleCouponDistribtionManager;
    
    @Autowired
    private DistributionManager distributionManager;
    
    @Autowired
    private PresaleCouponOrderOperateRecordManager operateRecordManager;
    
    @Autowired
    private PresaleCouponOrderAfterSalesManager afterSalesManager;
    
    @Autowired
    private PresaleCouponOrderAfterSalesRecordManager afterSalesRecordManager;
    
    @Autowired
    private SalesUserWalletManager walletManager;
    
    @Autowired
    private PaymentOrderManager paymentOrderManager;
    
    public PresaleCouponOrder getForUser(Integer orderId, Integer userId) {
    	PresaleCouponOrderExample example = new PresaleCouponOrderExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andOrderIdEqualTo(orderId).andUserIdEqualTo(userId).andDeletedEqualTo(PresaleCouponOrder.NOT_DELETED);
		return dao.selectOneByExample(example);
	}

	public Pagination<PresaleCouponOrder> queryForUser(Integer storeId, Integer status, Integer userId, Page page) {
		PresaleCouponOrderExample example = new PresaleCouponOrderExample();
		Criteria criteria = example.createCriteria();
		if(Check.notNull(status)) {
			criteria.andStatusEqualTo(status);
		}
		criteria.andStoreIdEqualTo(storeId).andUserIdEqualTo(userId).andDeletedEqualTo(PresaleCouponOrder.NOT_DELETED);
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());
		example.orderBy(Column.createTime.desc());
		return Pagination.create(page, 
			dao.countByExample(example),
			() -> dao.selectByExample(example));
	}
	
	public PresaleCouponOrder get(Integer orderId) {
		return dao.selectByPrimaryKey(orderId);
	}

	public Pagination<PresaleCouponOrder> query(QueryPresaleCouponOrderDTO query, Page page) {
		return Pagination.create(page, 
			dao.count(query),
			() -> dao.query(query, page));
	}
	
	/**
	 * 提交订单
	 * @param submit
	 * @param createUser
	 * @return
	 */
	@Transactional
	public PresaleCouponOrder submit(SubmitPresaleCouponOrderDTO submit, String createUser){
		PresaleCoupon presaleCoupon = presaleCouponManager.getPresaleCouponForUser(submit.getPreCouponId());
		BizAssert.isTrue(Check.notNull(presaleCoupon),ResultCode.BIZ.build(1), "预售券不存在或已下线");
		//录入订单
		PresaleCouponOrder order = new PresaleCouponOrder();
		order.setOrderNo(createOrderNo());
		order.setUserId(submit.getUserId());
		order.setUserName(submit.getUserName());
		order.setUserPhone(submit.getUserPhone());
		order.setStoreId(presaleCoupon.getStoreId());
		order.setTotalPrice(presaleCoupon.getRealPrice());
		order.setRealPrice(presaleCoupon.getRealPrice());
		order.setRemark(submit.getRemark());
		order.setStatus(PresaleCouponOrderStatus.WAIT_PAY.real());
		if(Check.notNullAndGtZero(submit.getSalesUserId())) {
			order.setSalesUserId(submit.getSalesUserId());
			//计算佣金
			BigDecimal commission = calcCommission(submit.getSalesUserId(),presaleCoupon.getStoreId(),submit.getPreCouponId(),presaleCoupon.getRealPrice());
			order.setCommission(commission);
		}
		order.setDeleted(PresaleCouponOrder.NOT_DELETED);
		order.setCreateUser(createUser);
		order.setCreateTime(Date.from(Instant.now()));
		order.setUpdateUser(createUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.insert(order);
		//处理订单明细
		PresaleCouponOrderDetail detail = detailManager.create(order.getOrderId(), presaleCoupon, createUser);
		//锁定库存
		Boolean succeed = presaleCouponManager.addUsedStockNumber(submit.getPreCouponId(), 1, createUser);
		BizAssert.isTrue(succeed,ResultCode.BIZ.build(2), "商品 【{}】库存不足", detail.getName());
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.SUBMIT_ORDER.real(), 
			submit.getRemark(),
			null, 
			createUser);
		return order;
	}
	
	/**
	 * 计算佣金
	 * @param salesUserId
	 * @param preCouponId
	 */
	public BigDecimal calcCommission(Integer salesUserId,Integer storeId, Integer preCouponId, BigDecimal realPrice) {
		SalesUser salesUser = salesUserManager.getByUserIdAndStoreId(salesUserId, storeId);
		List<PresaleCouponDistribtion> list = presaleCouponDistribtionManager.queryByPreCouponId(preCouponId);
		PresaleCouponDistribtion presaleCouponDistribtion = list.stream().collect(
			CollectorUtil.first(
				o -> distributionManager.getDistribution(o.getDistributionId())
				.getDepartmentId()
				.equals(salesUser.getDepartmentId())));
		if(Check.notNull(presaleCouponDistribtion)) {
			Distribution distribution = distributionManager.getDistribution(presaleCouponDistribtion.getDistributionId());
			if(Check.notNull(distribution)) {
				if(DistributionType.PROPORTION.equal(distribution.getType())) {
					//按比例分销,保留2位小数，直接舍弃后续小数
					return realPrice.multiply(distribution.getDistributionRatio()).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_DOWN);
				}else if(DistributionType.AMOUNT.equal(distribution.getType())) {
					//按金额分销
					return distribution.getDistributionAmt();
				}
			}
		}
		return BigDecimal.ZERO;
	}

	/**
	 * 提交线下付款
	 * @param order 订单
	 * @param updateUser 更新人
	 * @return 订单
	 */
	public PresaleCouponOrder applyOfflinePay(PresaleCouponOrder order, String updateUser){
		order.setPaymentType(PresaleCouponOrderPaymentType.OFFLINE_PAY.real());
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.paymentType, Column.updateUser, Column.updateTime);
		return order;
	}

	/**
	 * 券码核销
	 * @param couponCode
	 * @param updateUser
	 * @return
	 */
	@Transactional
	public Boolean couponCodeVerify(Integer storeId, String couponCode, String updateUser){
		PresaleCouponOrderDetail orderDetail = detailManager.couponCodeVerify(couponCode, updateUser);
		PresaleCouponOrder order = get(orderDetail.getOrderId());
		BizAssert.isTrue(PresaleCouponOrderStatus.canVerify(order.getStatus()), ResultCode.BIZ.build(10), "订单状态无法核销，请刷新页面后重试");
		BizAssert.isTrue(Check.eq(storeId, order.getStoreId()),ResultCode.BIZ.build(11), "券码错误");
		order.setStatus(PresaleCouponOrderStatus.USED.real());
		order.setUseTime(Date.from(Instant.now()));
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//发放佣金
		if(Check.notNull(order.getSalesUserId()) &&
			PresaleCouponDistributionSettleType.OTHER.equal(orderDetail.getDistributionSettleType())) {
			walletManager.waitInToBalance(order, updateUser);
		}
		//记录订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.VERIFY.real(), 
			null,
			couponCode, 
			updateUser);
		return true;
	}
	
	/**
	 * 撤销核销
	 * @param order
	 * @param updateUser
	 * @return
	 */
	@Transactional
	public Boolean cancelVerify(PresaleCouponOrder order, String remark, String updateUser){
		PresaleCouponOrderDetail orderDetail = detailManager.cancelVerify(order.getOrderId(), updateUser);
		BizAssert.isTrue(PresaleCouponOrderStatus.canCancelVerify(order.getStatus()), ResultCode.BIZ.build(10), "订单状态无法撤销，请刷新页面后重试");
		order.setStatus(PresaleCouponOrderStatus.WAIT_USE.real());
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		int row = dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//扣除佣金
		if(Check.notNull(order.getSalesUserId())) {
			walletManager.reduceWaitInOrBalance(order, updateUser);
		}
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.CANCEL_VERIFY.real(), 
			remark,
			orderDetail.getCouponCode(), 
			updateUser);
		return row == 1;
	}

	/**
	 * 后台确认线下支付成功
	 * @param order
	 * @param updateUser
	 * @return
	 */
	public PresaleCouponOrder confirmOfflinePay(PresaleCouponOrder order, String updateUser){
		Date now = Date.from(Instant.now());
		order.setStatus(PresaleCouponOrderStatus.WAIT_USE.real());
		order.setPaymentTime(now);
		order.setUpdateUser(updateUser);
		order.setUpdateTime(now);
		dao.updateByPrimaryKeySelective(order,Column.status,Column.paymentTime,Column.offlinePayEvidence,Column.updateUser,Column.updateTime);
		baseOperate(order,updateUser);
		return order;
	}

	/**
	 * 后台发起退款
	 * @param order
	 * @param updateUser
	 * @return
	 */
	public PresaleCouponOrder refund(PresaleCouponOrder order, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderStatus.canRefund(order.getStatus()),ResultCode.BIZ.build(10), "订单状态无法发起退款");
		if(PresaleCouponOrderPaymentType.WECHAT_PAY.real().equals(order.getPaymentType())){
			Boolean flag = paymentOrderManager.refundApply(
					order.getOrderNo(),
					order.getRealPrice(),
					null,
					order.getStoreId(),
					updateUser);
			BizAssert.isTrue(flag,ResultCode.BIZ.build(11), "发起退款失败");
		}
		order.setStatus(PresaleCouponOrderStatus.CLOSE.real());
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		int row = dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//售后单
		PresaleCouponOrderAfterSales afterSales = afterSalesManager.create(order, 
			PresaleCouponOrderAfterSalesType.REFUND, 
			PresaleCouponOrderAfterSalesStatus.SUCCESS, 
			null, 
			null, 
			null, 
			updateUser);
		//售后记录
		afterSalesRecordManager.create(afterSales.getAfterSalesId(), 
			order.getOrderId(),
			PresaleCouponOrderAfterSalesRecordType.MERCHANT_REFUND, 
			null, 
			null, updateUser);
		BizAssert.isTrue(row == 1,ResultCode.BIZ.build(12), "退款失败");
		//退还库存
		recoverStockNumber(order.getOrderId(), updateUser);
		//扣除佣金
		if(Check.notNull(order.getSalesUserId())) {
			walletManager.reduceWaitInOrBalance(order, updateUser);
		}
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.ADMIN_REFUND.real(), 
			null,
			null, 
			updateUser);
		return order;
	}
	
	/**
	 * 用户发起退款
	 * @param order
	 * @param remark
	 * @param evidenceImage
	 * @param updateUser
	 * @return
	 */
	@Transactional
	public PresaleCouponOrder applyRefund(PresaleCouponOrder order, String remark, String evidenceImage, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderStatus.canRefund(order.getStatus()),ResultCode.BIZ.build(10), "订单状态无法发起退款");
		order.setStatus(PresaleCouponOrderStatus.AFTER_SALES.real());
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		int row = dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//售后单
		PresaleCouponOrderAfterSales afterSales = afterSalesManager.create(order, 
			PresaleCouponOrderAfterSalesType.REFUND, 
			PresaleCouponOrderAfterSalesStatus.WAIT, 
			remark, 
			evidenceImage, 
			null, 
			updateUser);
		//售后记录
		afterSalesRecordManager.create(afterSales.getAfterSalesId(), 
			order.getOrderId(),
			PresaleCouponOrderAfterSalesRecordType.APPLY_REFUND, 
			remark, 
			evidenceImage, 
			updateUser);
		BizAssert.isTrue(row == 1,ResultCode.BIZ.build(11), "发起退款失败");
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.APPLY_AFTER_SALES.real(), 
			remark,
			null, 
			updateUser);
		return order;
	}
	
	/**
	 * 后台同意退款
	 * @param updateUser
	 * @return
	 */
	public void agreeRefund(Integer orderId, String updateUser) {
		PresaleCouponOrder order = get(orderId);
		if(PresaleCouponOrderPaymentType.WECHAT_PAY.real().equals(order.getPaymentType())){
			Boolean flag = paymentOrderManager.refundApply(
					order.getOrderNo(),
					order.getRealPrice(),
					null,
					order.getStoreId(),
					updateUser);
			BizAssert.isTrue(flag,ResultCode.BIZ.build(12), "发起退款失败");
		}
		order.setStatus(PresaleCouponOrderStatus.CLOSE.real());
		baseSetOrderStatus(order, updateUser);
		//退还库存
		recoverStockNumber(order.getOrderId(), updateUser);
		//扣除佣金
		if(Check.notNull(order.getSalesUserId())) {
			walletManager.reduceWaitInOrBalance(order, updateUser);
		}
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.AGREE_AFTER_SALES.real(), 
			null,
			null, 
			updateUser);
	}
	
	/**
	 * 后台拒绝退款
	 * @param updateUser
	 * @return
	 */
	public void refuseRefund(Integer orderId, String updateUser) {
		PresaleCouponOrder order = get(orderId);
		order.setStatus(PresaleCouponOrderStatus.WAIT_USE.real());
		baseSetOrderStatus(order, updateUser);
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.REFUSE_AFTER_SALES.real(), 
			null,
			null, 
			updateUser);
	}
	
	/**
	 * 用户取消售后
	 * @param orderId
	 * @param updateUser
	 */
	public void cancelAfterSales(Integer orderId, String updateUser) {
		PresaleCouponOrder order = get(orderId);
		order.setStatus(PresaleCouponOrderStatus.WAIT_USE.real());
		baseSetOrderStatus(order, updateUser);
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.USER_CANCEL_AFTER_SALES.real(), 
			null,
			null, 
			updateUser);
	}
	
	private void baseSetOrderStatus(PresaleCouponOrder order, String updateUser) {
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
	}

	private String createOrderNo() {
		String orderNo = RandomUtil.randomInt(18);
		PresaleCouponOrder order = getByOrderNo(orderNo);
		if (Check.notNull(order)) {
			orderNo = createOrderNo();
		}
		return orderNo;
	}
	
	public PresaleCouponOrder getByOrderNo(String orderNo) {
		PresaleCouponOrderExample example = new PresaleCouponOrderExample();
		Criteria criteria = example.createCriteria();
		criteria.andOrderNoEqualTo(orderNo);
		return dao.selectOneByExample(example);
	}
	
	/**
	 * 支付通知
	 * @param updateUser
	 */
	public void payNotify(PaymentOrder paymentOrder, String updateUser) {
		//不是支付成功状态不更新
		if(PaymentOrderStatus.PAY_SUCCEED.notEqual(paymentOrder.getStatus())) {
			return;
		}
		PresaleCouponOrder order = new PresaleCouponOrder();
		order.setPaymentType(paymentOrder.getPaymentType());
		order.setPaymentNo(paymentOrder.getPaymentNo());
		order.setPaymentTime(paymentOrder.getPaymentTime());
		order.setStatus(PresaleCouponOrderStatus.WAIT_USE.real());
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		
		// 获取订单数据, 就算删除也不管. 先更新订单状态
		PresaleCouponOrderExample example = new PresaleCouponOrderExample();
		example.createCriteria().andOrderNoEqualTo(paymentOrder.getOrderNo())
		// 为了处理临界值状态,被取消的订单照样能被修改为支付完成
		.andStatusIn(Lists.newArrayList(PresaleCouponOrderStatus.WAIT_PAY.real(),
			PresaleCouponOrderStatus.CANCEL.real(),
			PresaleCouponOrderStatus.AUTO_CANCEL.real()));
		
		dao.updateByExampleSelective(order,
			example,
			Column.paymentType,
			Column.paymentNo,
			Column.paymentTime,
			Column.status,
			Column.updateUser,
			Column.updateTime);
		//检查是否需要发放佣金
		PresaleCouponOrder presaleCouponOrder = getByOrderNo(paymentOrder.getOrderNo());
		baseOperate(presaleCouponOrder,updateUser);
	}

	/**
	 * 订单支付成功后的结算操作
	 * @param presaleCouponOrder
	 * @param updateUser
	 */
	private void baseOperate(PresaleCouponOrder presaleCouponOrder, String updateUser){
		List<PresaleCouponOrderDetail> detailList = detailManager.queryByOrderId(presaleCouponOrder.getOrderId());
		Integer distributionSettleType = detailList.get(0).getDistributionSettleType();
		if(Check.notNull(presaleCouponOrder.getSalesUserId()) &&
				PresaleCouponDistributionSettleType.AFTER_PAY.equal(distributionSettleType)) {
			//支付后结算
			walletManager.grantCommissionEd(presaleCouponOrder, updateUser);
		}else if(Check.notNull(presaleCouponOrder.getSalesUserId()) &&
				PresaleCouponDistributionSettleType.OTHER.equal(distributionSettleType)) {
			//支付后发放，使用后结算
			walletManager.grantCommissionIng(presaleCouponOrder, updateUser);
		}
		//增加销量
		detailList.forEach(detail -> {
			presaleCouponManager.addSaleNumber(detail.getPreCouponId(), 1, updateUser);
		});
		//发放券码
		detailList.forEach(detail -> {
			detailManager.update(detail, updateUser);
		});
		//订单操作记录
		operateRecordManager.create(presaleCouponOrder.getOrderId(),
				PresaleCouponOrderOperateRecordType.PAY_ORDER.real(),
				null,
				null,
				updateUser);
	}
	
	/**
	 * 退款通知
	 * @param updateUser
	 */
//	public void refundNotify(PaymentOrder paymentOrder, String updateUser) {
//		//不是退款成功状态不更新
//		if(PaymentOrderStatus.REFUND_SUCCEED.notEqual(paymentOrder.getStatus())) {
//			//处理售后单
//			afterSalesManager.updateAfterSalesStatus(paymentOrder.getOrderNo(), 
//				PresaleCouponOrderAfterSalesStatus.CLOSE.real(), updateUser);
//			return;
//		}
//		PresaleCouponOrder order = new PresaleCouponOrder();
//		order.setStatus(PresaleCouponOrderStatus.CLOSE.real());
//		order.setUpdateUser(updateUser);
//		order.setUpdateTime(Date.from(Instant.now()));
//		
//		PresaleCouponOrderExample example = new PresaleCouponOrderExample();
//		example.createCriteria().andOrderNoEqualTo(paymentOrder.getOrderNo())
//		.andStatusEqualTo(PresaleCouponOrderStatus.AFTER_SALES.real());
//		dao.updateByExampleSelective(order, example, Column.status, Column.updateUser, Column.updateTime);
//	}
	
	//恢复库存
	private void recoverStockNumber(Integer orderId, String updateUser) {
		List<PresaleCouponOrderDetail> detailList = detailManager.queryByOrderId(orderId);
		detailList.forEach(detail -> {
			Boolean succeed = presaleCouponManager.subtractUsedStockNumber(detail.getPreCouponId(), 1, updateUser);
			BizAssert.isTrue(succeed, ResultCode.BIZ.build(10), "商品[{}]恢复库存失败", detail.getName());
		});
	}

	/**
	 * 取消订单
	 * @param order
	 * @param updateUser
	 * @return
	 */
	public PresaleCouponOrder cancel(PresaleCouponOrder order, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderStatus.canCancel(order.getStatus()),ResultCode.BIZ.build(1), "订单状态无法取消");
		order.setStatus(PresaleCouponOrderStatus.CANCEL.real());
		order.setCancelTime(Date.from(Instant.now()));
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//释放库存
		recoverStockNumber(order.getOrderId(), updateUser);
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.CANCEL_ORDER.real(), 
			null,
			null, 
			updateUser);
		return order;
	}
	
	/**
	 * 自动取消订单
	 * @param order
	 * @param updateUser
	 * @return
	 */
	public PresaleCouponOrder autoCancel(PresaleCouponOrder order, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderStatus.canCancel(order.getStatus()),ResultCode.BIZ.build(1), "订单状态无法取消");
		order.setStatus(PresaleCouponOrderStatus.AUTO_CANCEL.real());
		order.setCancelTime(Date.from(Instant.now()));
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.status,Column.updateUser,Column.updateTime);
		//释放库存
		recoverStockNumber(order.getOrderId(), updateUser);
		//订单操作记录
		operateRecordManager.create(order.getOrderId(), 
			PresaleCouponOrderOperateRecordType.AUTO_CANCEL_ORDER.real(), 
			null,
			null, 
			updateUser);
		return order;
	}

	@Transactional
	public PresaleCouponOrder delete(PresaleCouponOrder order, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderStatus.canDel(order.getStatus()),ResultCode.BIZ.build(1), "订单状态无法删除");
		order.setDeleted(PresaleCouponOrder.IS_DELETED);
		order.setUpdateUser(updateUser);
		order.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(order, Column.deleted,Column.updateUser,Column.updateTime);
		//删除订单明细
		detailManager.deleteByOrderId(order.getOrderId(), updateUser);
		return order;
	}
	
	public List<PresaleCouponOrder> queryUnpaid(int size){
		PresaleCouponOrderExample example = new PresaleCouponOrderExample();
		Criteria criteria = example.createCriteria();
		criteria.andStatusEqualTo(PresaleCouponOrderStatus.WAIT_PAY.real());
		example.orderBy(Column.createTime.desc());
		example.limit(size);
		return dao.selectByExample(example);
	}
	
	/**
	 * 查询订单明细的预售券是否可退款
	 * @param orderId
	 * @return
	 */
	public Boolean presaleCouponCanRefund(Integer orderId) {
		List<PresaleCouponOrderDetail> list = detailManager.queryByOrderId(orderId);
		PresaleCoupon presaleCoupon = presaleCouponManager.getPresaleCoupon(list.get(0).getPreCouponId());
		return presaleCoupon.getIsRefund() == 1;
	}
}